﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Dynamic;
using System.Transactions;
using PagedList;
using Sovigaz.DataProvider;
using Utilities;

namespace Sovigaz.Permission.Repositories
{
    public class DeliveryPlanRepository : GenericRepository
    {
        public DeliveryPlanRepository()
            : base("DeliveryPlanID")
        {
        }

        public ICollection<DeliveryPlanComplex> DeliveryPlans { get; set; }

        #region Get

        public DeliveryPlanRepository GetList(string whereClause, string orderBy, string orderDirection, int pageNumber)
        {
            var deliveryPlans = _context.DeliveryPlans
                .Select(d => new DeliveryPlanComplex()
                {
                    DeliveryPlanID = d.DeliveryPlanID,
                    UserID = d.UserID,
                    UserName = d.UserID == 0 ? string.Empty : _context.Users.FirstOrDefault(us => us.UserID == d.UserID).Username,
                    FullName = d.UserID == 0 ? string.Empty : _context.Users.FirstOrDefault(us => us.UserID == d.UserID).FullName,
                    LicensePlate = d.LicensePlate,
                    DeliveryPlanCode = d.DeliveryPlanCode,
                    DeliveryType = d.DeliveryType,
                    Date = d.Date,
                    Status = d.Status,
                    Description = d.Description,
                    UpdatedName = _context.Users.FirstOrDefault(us => us.UserID == d.UpdatedBy).FullName,
                    UpdatedDate = d.UpdatedDate,
                    IsDeleted = d.IsDeleted
                })
                .Where(whereClause)
                .OrderBy(String.Format("{0} {1}", orderBy.Trim(), orderDirection.Trim()))
                .ToPagedList(pageNumber, DefaultPageSize);

            TotalItemCount = deliveryPlans.TotalItemCount;
            TotalItemOnPage = deliveryPlans.Count;
            PageCount = deliveryPlans.PageCount;
            PageNumber = deliveryPlans.PageNumber;
            DeliveryPlans = deliveryPlans.ToList();

            return this;
        }

        public DeliveryPlan GetByID(int id)
        {
            DeliveryPlan deliveryPlan = _context.DeliveryPlans.FirstOrDefault(p => p.DeliveryPlanID == id && !p.IsDeleted);
            if (deliveryPlan == null) return deliveryPlan;
            var repository = new DeliveryPlanLineRepository();
            deliveryPlan.DeliveryPlanLines = repository.GetByDeliveryPlanID(deliveryPlan.DeliveryPlanID);
            return deliveryPlan;
        }

        #endregion

        #region Put

        public int Update(DeliveryPlan deliveryPlan)
        {
            if (deliveryPlan.DeliveryPlanLines.Count <= 0)
                return -1;
            var update = new DeliveryPlan();
            var re = new DeliveryPlanLineRepository();
            update.DeliveryPlanCode = GenerateCode.GetCode(GetNextIndex(), CodeType.DeliveryPlan);
            using (var scope = new TransactionScope())
            {
                if (deliveryPlan.DeliveryPlanID > 0)
                {
                    update = GetByID(deliveryPlan.DeliveryPlanID);
                    re.Delete(update);
                    if (!Utility.ArrayEqual(update.Tstamp, deliveryPlan.Tstamp))
                        throw ExceptionHelper.CreateHttpResponseException("Dữ liệu đã bị cập nhật bởi người sử dụng khác.");
                }
                update.DeliveryPlanID = deliveryPlan.DeliveryPlanID;
                update.Date = deliveryPlan.Date;
                update.UserID = deliveryPlan.UserID;
                update.BocXep1 = deliveryPlan.BocXep1;
                update.BocXep2 = deliveryPlan.BocXep2;
                update.BocXep3 = deliveryPlan.BocXep3;
                update.LicensePlate = deliveryPlan.LicensePlate;
                update.Status = deliveryPlan.Status;
                update.DeliveryType = deliveryPlan.DeliveryType;
                update.Description = deliveryPlan.Description;

                if (update.DeliveryPlanID == 0)
                    _context.DeliveryPlans.Add(update);
                _context.SaveChanges();

                
                re.Update(deliveryPlan.DeliveryPlanLines, update.DeliveryPlanID, scope);

                scope.Complete();
            }

            _context.Entry(update).Reload();

            return update.DeliveryPlanID;
        }

        #endregion

        #region Delete

        public void Delete(int id)
        {
            var item = GetByID(id);
            var repository = new DeliveryPlanLineRepository();
            var commandrepository = new CommandRepository();
                     
            if (item.Status == "N")
            {
                _context.DeliveryPlans.Remove(item);
                repository.DeleteByDeliveryPlanID(id, true);
            }
            else if (item.Status == "I")
            {      
                commandrepository.Delete(commandrepository.GetByDeliveryPlanID(item.DeliveryPlanID).CommandID);
                _context.DeliveryPlans.Remove(item);
                repository.DeleteByDeliveryPlanID(ConvertUtility.IntParse(id), true);
            }
            _context.SaveChanges();
        }

        public void Delete(string[] idArr)
        {
            foreach (var id in idArr)
            {
                var item = GetByID(ConvertUtility.IntParse(id));
                var repository = new DeliveryPlanLineRepository();
                var commandrepository = new CommandRepository();
                if (item.Status == "N")
                {
                    _context.DeliveryPlans.Remove(item);
                    repository.DeleteByDeliveryPlanID(ConvertUtility.IntParse(id), true);
                }
                else if (item.Status == "I")
                {
                    commandrepository.Delete(commandrepository.GetByDeliveryPlanID(item.DeliveryPlanID));
                    _context.DeliveryPlans.Remove(item);
                    repository.DeleteByDeliveryPlanID(ConvertUtility.IntParse(id), true);
                }
            }

            _context.SaveChanges();
        }

        #endregion              

        public int GetNextIndex()
        {
            if (_context.DeliveryPlans.FirstOrDefault() == null) return 1;
            return _context.DeliveryPlans.Max(p => p.DeliveryPlanID) + 1;
        }

        public void UpdateStatus(int id, string status)
        {
            var item = GetByID(id);
            if (item.DeliveryType == "IN" && status == "I") return;
                item.Status = status;
            _context.SaveChanges();
        }

        public void UpdateStatus(string[] ids, string status)
        {
            foreach (var id in ids)
                UpdateStatus(ConvertUtility.IntParse(id), status);
        }

        public bool canEdit(int id)
        {
            if (id == 0) return true;
            if (GetByID(id).Status == "N")
                return true;
            return false;
        }
        
    }
}
